feat(simctl): Add clone, create, and delete simulator management commands#418
feat(simctl): Add clone, create, and delete simulator management commands#418yjmeqt wants to merge 8 commits into
Conversation
…ands Wraps xcrun simctl clone, create, and delete as MCP/CLI tools, registered under the simulator-management workflow. Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
Use NonStreamingExecutor pattern with SimulatorActionResultDomainResult, add action types to domain-results and renderer labels. Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
commit: |
- Fix publicSchemaObject to not omit non-session-default params - Capture new simulator UDID from simctl clone/create stdout - Allow shutdownFirst for delete_sims with target=all - Add tests for clone, create, and delete tools Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
…on-result schema Co-Authored-By: DeepSeek V4 Pro <noreply@deepseek.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4f8fef6. Configure here.
Require clone_sims callers to provide the new simulator name that simctl expects. Avoid reporting the source simulator as a clone artifact when the clone command fails. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Align clone, create, and delete simulator tools with the current simulator-action-result contract. The shared v2 schema accepts optional top-level nextSteps and now includes the new action metadata variants. Co-Authored-By: OpenAI Codex <noreply@openai.com>
| return; | ||
| } | ||
|
|
||
| const newSimulatorId = result.artifacts?.simulatorId ?? params.sourceSimulatorId; |
There was a problem hiding this comment.
Bug: If xcrun simctl clone returns an empty UDID, the tool incorrectly falls back to the sourceSimulatorId, causing subsequent actions to target the original simulator instead of the clone.
Severity: HIGH
Suggested Fix
Modify the logic in clone_sims.ts to prevent falling back to sourceSimulatorId. If a valid clonedSimulatorId cannot be determined from the command output, subsequent tool suggestions like boot_sim should not be provided with a simulatorId, similar to the behavior in the create_sim tool. This ensures that actions are not accidentally performed on the source simulator.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: src/mcp/tools/simulator-management/clone_sims.ts#L118
Potential issue: In the `clone_sims` tool, if the `xcrun simctl clone` command succeeds
but fails to return a UDID (resulting in an empty string), the logic incorrectly falls
back to using the `sourceSimulatorId`. This happens because an empty `clonedSimulatorId`
is falsy, causing the `artifacts` object to be omitted from the result. Consequently,
the nullish coalescing operator on line 118 assigns `params.sourceSimulatorId` to
`newSimulatorId`. This incorrect ID is then used in suggestions for subsequent tools
like `boot_sim` and `install_app_sim`, causing them to operate on the original source
simulator instead of the newly created clone, defeating the purpose of the cloning
operation.
Also affects:
src/mcp/tools/simulator-management/clone_sims.ts:84~88
|
Thanks @yjmeqt for putting this together — I appreciate the work here and the direction of improving simulator management. I’ve thought this through against the original issue (#414), and I’m not convinced the current shape delivers enough value yet. The issue is really about simulator isolation for concurrent XcodeBuildMCP usage: multiple workspaces, branches, or MCP instances may target the same simulator and interfere with each other. In that context, exposing I think the valuable abstraction would be higher-level, something closer to “ensure/allocate an isolated simulator”:
The low-level primitives may still be useful internally as building blocks, but I don’t think they should be the main user-facing feature for this issue. I’d prefer we reshape this PR around the simulator-isolation workflow, or narrow it explicitly as internal groundwork and follow up with the actual allocation/ownership behavior. |
|
One more note, @yjmeqt: if we continue with any version of these tool changes, the PR also needs the required snapshot fixtures/tests added for the new public tool contracts. The contribution docs call this out here:
For new/changed tools, we should have representative fixtures for MCP text, MCP structured JSON, CLI text, and CLI JSON, plus schema fixture validation for structured output. That is especially important here because these tools expose new public CLI/MCP behavior. |

Summary
clone_sims(xcrun simctl clone) — clone an existing simulatorcreate_sim(xcrun simctl create) — create a new simulatordelete_sims(xcrun simctl delete) — delete by UDID, all, or unavailable simulators (withshutdownFirstoption)simulator-managementworkflowCloses #414
Test plan
npm run buildsucceeds